package org.example;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.text.StrSplitter;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import org.junit.Test;
import team.first.moviedb.entity.*;

import java.sql.SQLException;
import java.util.List;

/**
 * 电影编号###电影片名###电影中文名###电影别名###上映年份###地区###电影片长###语言###上映时间###电影简介###海报地址###分值###
 * 影片类型列表(类型编号-+-类型名称)###
 * 导演列表(编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址=|=编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址)###
 * 演员列表(编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址-+-片中角色名=|=(编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址-+-片中角色名)$$$
 */
public class ParsingPro {

    private static final String FIELD_TAG = "###";
    private static final String SPLIT_TAG_ONE = "-+-";
    private static final String SPLIT_TAG_TWO = "=|=";
    private static final String LINE_END_TAG = "$$$";

    @Test
    public void test01() throws Exception {
        // 利用hutool文件工具类读取文件
        FileReader fileReader = new FileReader("movie_data_v3.txt");
        List<String> stringList = fileReader.readLines();
        StringBuffer sb = new StringBuffer();

        for (String s : stringList) {
            // 判断是否一条数据已读完
            if (!s.endsWith(LINE_END_TAG)) {
                sb.append(s);
                continue;
            }

            Movie movie = new Movie();

            // 当前字符串s是包含 $$$ 的一行
            sb.append(StrSplitter.split(s, LINE_END_TAG, 0, true, false).get(0));

            // 读取完一个完整的数据
            String movieString = String.valueOf(sb);

            // 第一次拆分，根据###
            List<String> tuple = StrSplitter.split(movieString, FIELD_TAG, 0, true, false);

            // 第一个是电影编号
            //String movieId = tuple[0];
            movie.setId(Convert.toInt(tuple.get(0)));

            // 第二个是电影片名
            movie.setName(tuple.get(1));

            // 第三个是电影中文名
            movie.setChineseName(tuple.get(2));

            // 第四个是电影别名
            movie.setAlias(tuple.get(3));

            // 第五个是上映年份
            movie.setReleaseDate(Convert.toInt(tuple.get(4)));

            // 第六个是地区
            //String location = tuple[5];
            movie.setRegion(tuple.get(5));

            // 第七个是电影片长
            movie.setTimeDuration(tuple.get(6));

            // 第八个是语言
            movie.setLanguage(tuple.get(7));

            // 第九个是上映时间
            movie.setReleaseTime(tuple.get(8));

            // 第十个是电影简介
            movie.setIntroduction(tuple.get(9));

            // 第11个是海报地址
            movie.setPostersAddress(tuple.get(10));

            // 第12个是分值
            movie.setScore(Convert.toInt(tuple.get(11)));

            // 影片类型列表(类型编号-+-类型名称)###
            // 第13个是影片类型列表(类型编号:类型名称)
            String movieType = tuple.get(12);

            // 对影片类型列表进行分割
            // 第一次分解出每个类型
            List<String> movieTypeSplit = StrSplitter.split(movieType, SPLIT_TAG_TWO, 0, true, false);
            for (String t : movieTypeSplit) {
                if (t.length() <= 1)
                    continue;
                // 对每个类型在进行解析
                List<String> ts = StrSplitter.split(t, SPLIT_TAG_ONE, 0, true, false);
                Type type = new Type(Convert.toInt(ts.get(0)), ts.get(1));
                try {
                    insertType(type);
                } catch (Exception e) {

                }
                insertMovieType(movie, type);
            }

            //  * 导演列表(编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址=|=编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址)###
            // 第14个是导演列表(编号:中文名:英文名:性别:地区:生日:简介:照片地址)
            String directorList = tuple.get(13);
            if (directorList.length() != 0) {
                // 解析出每一个导演
                List<String> directorListSplit = StrSplitter.split(directorList, SPLIT_TAG_TWO, 0, true, false);

                for (String d : directorListSplit) {
                    if (d.length() <= 1)
                        continue;
                    // 对每个导演进行解析
                    List<String> ds = StrSplitter.split(d, SPLIT_TAG_ONE, 0, true, false);

                    // 导演没有片中角色名
                    Actor director = new Actor(Convert.toInt(ds.get(0)), ds.get(1), ds.get(2), ds.get(3), ds.get(4), ds.get(5), ds.get(6), ds.get(7));
                    try{
                        insertActor(director);
                    } catch (Exception e) {

                    }

                    insertMovieActor(movie, director, 2, "导演");
                }
            }

            // 第15个是演员列表(编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址-+-片中角色名=|=
            // (编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址-+-片中角色名)$$$
            String actorList = tuple.get(14);

            // 解析出每一个演员
            List<String> split = StrSplitter.split(actorList, SPLIT_TAG_TWO, 0, true, false);
            // 演员列表(编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址-+-片中角色名=|=
            // (编号-+-中文名-+-英文名-+-性别-+-地区-+-生日-+-简介-+-照片地址-+-片中角色名)$$$
            for (String a : split) {
                if (a.length() <= 1)
                    continue;
                List<String> as = StrSplitter.split(a, SPLIT_TAG_ONE, 0, true, false);

                // 对每个演员进行解析
                Actor actor;
                String actAs = "";
                if (as.size() == 8) {
                    // 7340条
                    actor = new Actor(Convert.toInt(as.get(0)), as.get(1), as.get(2), as.get(3),
                            as.get(4), as.get(5), as.get(6), as.get(7));
                } else {
                    // 7592条
                    actor = new Actor(Convert.toInt(as.get(0)), as.get(1), as.get(2), as.get(3),
                            as.get(4), as.get(5), as.get(6), as.get(7));
                    actAs = as.get(8);
                }
                try {
                    insertActor(actor);
                } catch (Exception e) {

                }

                insertMovieActor(movie, actor, 1, actAs);
            }

            sb = new StringBuffer();
            insertMovie(movie);
        }
    }

    static void insertMovieType(Movie movie, Type type) throws SQLException {
        Db.use().insert(
                Entity.create("movie_api.type_with_movie")
                        .set("movie_id", movie.getId())
                        .set("type_id", type.getId())
        );
    }

    static void insertMovieActor(Movie movie, Actor actor, Integer identity, String actAs) throws SQLException {
        Db.use().insert(
                Entity.create("movie_api.movie_with_actor")
                        .set("movie_id", movie.getId())
                        .set("actor_id", actor.getId())
                        .set("status", identity)
                        .set("act_as", actAs)
        );
    }

    static void insertMovie(Movie movie) throws SQLException {
        Db.use().insert(
                Entity.create("movie_api.movie")
                        .set("id", movie.getId())
                        .set("name", movie.getName())
                        .set("chinese_name", movie.getChineseName())
                        .set("alias", movie.getAlias())
                        .set("release_date", movie.getReleaseDate())
                        .set("region", movie.getRegion())
                        .set("time_duration", movie.getTimeDuration())
                        .set("language", movie.getLanguage())
                        .set("release_time", movie.getReleaseTime())
                        .set("introduction", movie.getIntroduction())
                        .set("posters_address", movie.getPostersAddress())
                        .set("score", movie.getScore())
        );
    }

    static void insertType(Type type) throws SQLException {
        Db.use().insert(
                Entity.create("movie_api.type")
                        .set("id", type.getId())
                        .set("name", type.getName())
        );
    }

    static void insertActor(Actor actor) throws SQLException {
        Db.use().insert(
                Entity.create("movie_api.actor")
                        .set("id", actor.getId())
                        .set("name", actor.getName())
                        .set("english_name", actor.getEnglishName())
                        .set("gender", actor.getGender())
                        .set("region", actor.getRegion())
                        .set("birthday", actor.getBirthday())
                        .set("introduction", actor.getIntroduction())
                        .set("photo_path", actor.getPhotoPath())
        );
    }
}
